package com.cyzy.service;

import com.cyzy.dto.Message;
import com.cyzy.dto.MessageType;
import com.cyzy.mapper.MessageMapper;
import com.cyzy.sender.ChatProducer;
import lombok.RequiredArgsConstructor;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class MessageService {
    private final MessageMapper messageMapper;
    private final ChatProducer chatProducer; // 通过Spring注入，而非方法内创建


    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate ;
    @Transactional
    public String sendMessage(String fromUser,Integer toUserid, String toUser, String content) {
        Message message = new Message(fromUser, toUserid, toUser, content);
        Integer messageId = message.getMessageid();
        Message message1 = messageMapper.getMessageById(messageId);
        if (message1 != null) {
            String redisKey = "messages_" + message1.getToUserid();
            String redisKeys = "messages_unread_" + message1.getToUserid();
            redisTemplate.delete(redisKey);
            System.out.println("修改"+redisKey);
            redisTemplate.delete(redisKeys);
        }
        // 异步发送消息
        try {
            chatProducer.sendMessageAsync(fromUser, toUserid ,toUser, content, MessageType.MESSAGE,messageId, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    messageMapper.updateMessageStatus(messageId, "SUCCESS");
                }
                @Override
                public void onException(Throwable e) {
                    messageMapper.updateMessageStatus(messageId, "FAILED");
                    System.err.println("消息发送失败: " + e.getMessage());
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            System.err.println("消息发送异常: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("消息发送异常", e);
        }
        return ""+messageId;
    }
    
    @Transactional
    public String sendAnnouncement(String fromUser,Integer toUserid, String toUser, String content) {
        Message message = new Message(fromUser, toUserid, toUser, content);
        messageMapper.insertMessage(message);
        Integer messageId = message.getMessageid();
        Message message1 = messageMapper.getMessageById(messageId);
        if (message1 != null) {
            String redisKey = "messages_" + message1.getToUserid();
            String redisKeys = "messages_unread_" + message1.getToUserid();
            redisTemplate.delete(redisKey);
            System.out.println("修改"+redisKey);
            redisTemplate.delete(redisKeys);
        }
        // 异步发送消息
        try {
            chatProducer.sendMessageAsync(fromUser, toUserid ,toUser, content, MessageType.MESSAGE,messageId, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    messageMapper.updateMessageStatus(messageId, "SUCCESS");
                }
                @Override
                public void onException(Throwable e) {
                    messageMapper.updateMessageStatus(messageId, "FAILED");
                    System.err.println("公告发送失败: " + e.getMessage());
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            System.err.println("公告发送异常: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("公告发送异常", e);
        }

        return ""+messageId;
    }
    
    @Transactional
    public String insertMessage (String fromUser,Integer toUserid, String toUser, String content) {
        Message message = new Message(fromUser, toUserid, toUser, content);
        if (message != null) {
            String redisKey = "messages_" + toUserid;
            System.out.println("新加"+redisKey);
            String redisKeys = "messages_unread_" +toUserid;
            redisTemplate.delete(redisKey);
            redisTemplate.delete(redisKeys);
        }
        messageMapper.insertMessage(message);
        return ""+message;
    }
    //数据库更改由接收者执行
    @Transactional
    public String updateRead(Integer messageId) {
        int rows = messageMapper.updateMessageIsRead(messageId);
        if (rows <= 0) {
            throw new RuntimeException("更新已读状态失败，消息可能已处理或不存在，ID: " + messageId);
        }
        
        // 清除Redis缓存
        Message message = messageMapper.getMessageById(messageId);
        if (message != null) {
            String redisKey = "messages_" + message.getToUserid();
            String redisKeys = "messages_unread_" + message.getToUserid();
            redisTemplate.delete(redisKey);
            System.out.println("修改"+redisKey);
            redisTemplate.delete(redisKeys);
        }
        
        return " "+messageId;
    }
    //调用rocketmq异步发送修改消息
    @Transactional
    public String updateMessageIsRead(Integer messageId) throws Exception {
        // 先查询消息获取完整信息
        Message originalMessage = messageMapper.getMessageById(messageId);
        if (originalMessage == null) {
            throw new RuntimeException("消息不存在，ID: " + messageId);
        }

        updateRead(messageId);
        // 创建更新消息
        Message message = new Message();
        message.setMessageid(messageId);
        message.setFromUser(originalMessage.getFromUser());
        message.setToUserid(originalMessage.getToUserid());
        message.setToUser(originalMessage.getToUser());
        message.setMessageType(MessageType.UPDATE_MESSAGE);

        // 发送更新消息
        chatProducer.sendMessageAsync(
                message.getFromUser(),
                message.getToUserid(),
                message.getToUser(),
                "消息已读",
                message.getMessageType(),
                messageId,
                new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {
                        System.out.println("更新消息已成功发送到队列: " + messageId);
                    }

                    @Override
                    public void onException(Throwable e) {
                        System.err.println("发送更新消息失败: " + e.getMessage());
                        e.printStackTrace();
                    }
                }
        );
        return "发送修改消息成功" + messageId;
    }
    public List<Message> getUnreadMessages(Integer toUserid) {
        if (toUserid == null ) {
            throw new IllegalArgumentException("接收用户ID不能为空");
        }
        String messageKey = "messages_" + toUserid;
        // 从Redis获取缓存
        List<Message> messages = (List<Message>) redisTemplate.opsForValue().get(messageKey);
        if (messages != null) {
            return messages;
        }
        // 缓存未命中，查询数据库
        List<Message> newMessages = messageMapper.getMessageByToUser(toUserid);
        if (newMessages != null && !newMessages.isEmpty()) {
            int expireTime = (int) (Math.random() * 1000 + 10); // 10-20秒
            redisTemplate.opsForValue().set(messageKey, newMessages, expireTime, TimeUnit.SECONDS);
        }

        return newMessages;
    }
    public List<Message> getMessageByToUserByisRead(Integer toUserid) {
        if (toUserid == null ) {
            throw new IllegalArgumentException("接收用户ID不能为空");
        }
        String messageKey = "messages_unread_" + toUserid;
        // 从Redis获取缓存
        List<Message> messages = (List<Message>) redisTemplate.opsForValue().get(messageKey);
        if (messages != null) {
            return messages;
        }
        // 缓存未命中，查询数据库
        List<Message> newMessages = messageMapper.getMessageByToUserByisRead(toUserid);
        if (newMessages != null && !newMessages.isEmpty()) {
            int expireTime = (int) (Math.random() * 1000 + 10); // 10-20秒
            redisTemplate.opsForValue().set(messageKey, newMessages, expireTime, TimeUnit.SECONDS);
        }
        return newMessages;
    }


    public Message getMessageById(Integer messageId) {
        return messageMapper.getMessageById(messageId);
    }
}